package moyenDeTransport;

import java.io.*;
import java.util.Calendar;
import java.util.Date;

import serveur.Serveur;

/**
 * Cette classe fait partie de l'application d'un système de réservation de
 * moyens de transport en commun.
 * 
 * Cette classe permet de stocker un Trajet. Un trajet est constitué d'une date
 * de départ et d'arrivée, d'un lieu de départ et d'arrivée, d'un véhicule, de
 * places restantes, d'un identifiant.
 * 
@author Fauconnier Simon  Bourdin Théo Jimenez Matthieu Shimabukuro Emmanuel

 */

public class Trajet implements Serializable, Comparable {
    Calendar dateDepart;
    Calendar dateArrivee;
    Ville depart;
    Ville arrivee;
    Vehicule vehicule;
    int capaciteRestantes;
    int placesPremieres;
    int placesSeconde;
    int placesEco;
    int identifiant;
    float prix;
    boolean couchette;
    boolean repas;

    /**
     * Crée une instance de trajet
     * 
     * @param dateDepart
     *            la date de départ
     * @param dateArrivee
     *            la date d'arrivée
     * @param depart
     *            le lieu de départ
     * @param arrivee
     *            le lieu d'arrivée
     * @param vehicule
     *            le véhicule
     * @param identifiant
     *            l'identifiant
     */
    public Trajet(Calendar dateDepart, Calendar dateArrivee, Ville depart,
            Ville arrivee, Vehicule vehicule, int identifiant) {
        this.dateDepart = dateDepart;
        this.dateArrivee = dateArrivee;
        this.depart = depart;
        this.arrivee = arrivee;
        this.vehicule = vehicule;
        this.placesPremieres = vehicule.getPremiereClasse();
        this.placesSeconde = vehicule.getSecondeClasse();
        this.placesEco = vehicule.getClasseEco();
        this.identifiant = identifiant;
        this.capaciteRestantes = placesPremieres + placesSeconde + placesEco;
    }

    /**
     * Crée une instance de trajet
     * 
     * @param dateDepart
     *            la date de départ
     * @param dateArrivee
     *            la date d'arrivée
     * @param depart
     *            le lieu de départ
     * @param arrivee
     *            le lieu d'arrivée
     * @param vehicule
     *            le véhicule
     * @param identifiant
     *            l'identifiant
     * @param placesRestantes
     *            le nombre de places restantes
     */
    public Trajet(Calendar dateDepart, Calendar dateArrivee, Ville depart,
            Ville arrivee, Vehicule vehicule, int identifiant, float prix) {
        this.dateDepart = dateDepart;
        this.dateArrivee = dateArrivee;
        this.depart = depart;
        this.arrivee = arrivee;
        this.vehicule = vehicule;
        this.identifiant = identifiant;
        this.prix = prix;
    }

    public Trajet(Calendar dateDepart, Calendar dateArrivee, Ville depart,
            Ville arrivee, Vehicule vehicule, int identifiant, float prix,
            boolean couchette, boolean repas, int placesPremieres,
            int placesSeconde, int placesEco) {
        this.dateDepart = dateDepart;
        this.dateArrivee = dateArrivee;
        this.depart = depart;
        this.arrivee = arrivee;
        this.vehicule = vehicule;
        this.placesPremieres = placesPremieres;
        this.placesSeconde = placesSeconde;
        this.placesEco = placesEco;
        this.identifiant = identifiant;
        this.prix = prix;
        this.couchette = couchette;
        this.repas = repas;
        this.capaciteRestantes = placesPremieres + placesSeconde + placesEco;
    }

    public int getCapaciteRestantes() {
        return capaciteRestantes;
    }

    public void setCapaciteRestantes(int capaciteRestantes) {
        this.capaciteRestantes = capaciteRestantes;
    }

    public int getPlacesPremieres() {
        return placesPremieres;
    }

    public void setPlacesPremieres(int placesPremieres) {
        this.placesPremieres = placesPremieres;
    }

    public int getPlacesSeconde() {
        return placesSeconde;
    }

    public void setPlacesSeconde(int placesSeconde) {
        this.placesSeconde = placesSeconde;
    }

    public int getPlacesEco() {
        return placesEco;
    }

    public void setPlacesEco(int placesEco) {
        this.placesEco = placesEco;
    }

    public boolean isCouchette() {
        return couchette;
    }

    public void setCouchette(boolean couchette) {
        this.couchette = couchette;
    }

    public boolean isRepas() {
        return repas;
    }

    public void setRepas(boolean repas) {
        this.repas = repas;
    }

    /*
     * @return prix d'un billet
     */
    public float getPrix() {
        return prix;
    }

    /*
     * @param prix prix d'un billet
     */
    public void setPrix(int prix) {
        this.prix = prix;
    }

    /**
     * @return date de départ
     */
    public Calendar getDateDepart() {
        return dateDepart;
    }

    /**
     * @return date d'arrivée
     */
    public Calendar getDateArrivee() {
        return dateArrivee;
    }

    /**
     * @return lieu de départ
     */
    public Ville getDepart() {
        return depart;
    }

    /**
     * @return lieu d'arrivée
     */
    public Ville getArrivee() {
        return arrivee;
    }

    /**
     * @return véhicule du trajet
     */
    public Vehicule getVehicule() {
        return vehicule;
    }

    /**
     * @return identifiant du trajet
     */
    public int getIdentifiant() {
        return identifiant;
    }

    /**
     * @param dateDepart
     *            date de départ
     */
    public void setDateDepart(Calendar dateDepart) {
        this.dateDepart = dateDepart;
    }

    /**
     * @param dateArrivee
     *            date d'arrivée
     */
    public void setDateArrivee(Calendar dateArrivee) {
        this.dateArrivee = dateArrivee;
    }

    /**
     * @param depart
     *            lieu de départ
     */
    public void setDepart(Ville depart) {
        this.depart = depart;
    }

    /**
     * @param arrivee
     *            lieu d'arrivée
     */
    public void setArrivee(Ville arrivee) {
        this.arrivee = arrivee;
    }

    /**
     * @param vehicule
     *            véhicule du trajet
     */
    public void setVehicule(Vehicule vehicule) {
        this.vehicule = vehicule;
    }

    /**
     * @param identifiant
     *            identifiant du trajet
     */
    public void setIdentifiant(int identifiant) {
        this.identifiant = identifiant;
    }

    /**
     * Décrémente le nombre de places restantes en premiere classe
     * 
     * @param dec
     *            le décrémenteur
     */
    public void decPlacesPremieres(int dec) {
        this.placesPremieres -= dec;
    }

    /**
     * Décrémente le nombre de places restantes en seconde classe
     * 
     * @param dec
     *            le décrémenteur
     */
    public void decPlacesSeconde(int dec) {
        this.placesSeconde -= dec;
    }

    /**
     * Décrémente le nombre de places restantes en classe eco
     * 
     * @param dec
     *            le décrémenteur
     */
    public void decPlacesEco(int dec) {
        this.placesEco -= dec;
    }

    @Override
    public String toString() {
        int departMois = dateDepart.get(Calendar.MONTH) + 1;
        int arriveeMois = dateArrivee.get(Calendar.MONTH) + 1;

        return new StringBuffer().append("Voyage (id=").append(identifiant)
                .append(") de ").append(depart).append(" à ").append(arrivee)
                .append(" en ").append(vehicule.getVehicule()).append(" (id=")
                .append(vehicule.getIdentifiant()).append("): \n\t")
                .append("Départ le ").append(dateDepart.get(Calendar.DATE))
                .append("/").append(departMois).append("/")
                .append(dateDepart.get(Calendar.YEAR)).append(" à ")
                .append(dateDepart.get(Calendar.HOUR_OF_DAY)).append(":")
                .append(dateDepart.get(Calendar.MINUTE)).append("\n\t")
                .append("Arrivée le ").append(dateArrivee.get(Calendar.DATE))
                .append("/").append(arriveeMois).append("/")
                .append(dateArrivee.get(Calendar.YEAR)).append(" à ")
                .append(dateArrivee.get(Calendar.HOUR_OF_DAY)).append(":")
                .append(dateArrivee.get(Calendar.MINUTE)).append("\n\t")
                .append("Il reste ").append(placesPremieres)
                .append(" en premiere classe, ").append(placesSeconde)
                .append(" en seconde et ").append(placesEco)
                .append(" en class eco.").append(" avec un prix de ")
                .append(prix).toString();
    }

    /**
     * retourner une ligne de texte contenant les informations utiles pour
     * reconstituer un trajet, séparé par des '#'
     * 
     * @return la ligne de texte terminée par un '\n'
     */
    public String print() {
        return new StringBuffer().append(Serveur.calendarToDate(dateDepart))
                .append("#").append(Serveur.calendarToTime(dateDepart))
                .append("#").append(Serveur.calendarToDate(dateArrivee))
                .append("#").append(Serveur.calendarToTime(dateArrivee))
                .append("#").append(depart).append("#").append(arrivee)
                .append("#").append(vehicule.getIdentifiant()).append("#")
                .append(identifiant).append("#").append(prix).append("#")
                .append(couchette).append("#").append(repas).append("#")
                .append(placesPremieres).append("#").append(placesSeconde)
                .append("#").append(placesEco).append("#").append("\n")
                .toString();
    }

    // compare deux trajets suivant leur date de départ
    @Override
    public int compareTo(Object t) {
        if (this.getDateDepart().after(((Trajet) t).getDateDepart()))
            return 1;
        else if (this.getDateDepart().before(((Trajet) t).getDateDepart()))
            return -1;
        else
            return 0;
    }

    public boolean restePlaces(int placesDemandes) {
        if (placesDemandes <= this.getCapaciteRestantes()) {
            return true;
        }
        return false;
    }

    public boolean restePlacesPremieres(int placesDemandes) {
        if (placesDemandes <= this.getPlacesPremieres()) {
            return true;
        }
        return false;
    }

    public boolean restePlacesSeconde(int placesDemandes) {
        if (placesDemandes <= this.getPlacesSeconde()) {
            return true;
        }
        return false;
    }

    public boolean restePlacesEco(int placesDemandes) {
        if (placesDemandes <= this.getPlacesEco()) {
            return true;
        }
        return false;
    }

    public void decPremiereClasse(int dec) {
        this.placesPremieres = this.placesPremieres - dec;
        this.capaciteRestantes = this.capaciteRestantes - dec;
    }

    public void decSecondeClasse(int dec) {
        this.placesSeconde = this.placesSeconde - dec;
        this.capaciteRestantes = this.capaciteRestantes - dec;
    }

    public void decEcoClasse(int dec) {
        this.placesEco = this.placesPremieres - dec;
        this.capaciteRestantes = this.capaciteRestantes - dec;
    }
}
